import cv2
import mss
import time
import pyautogui
import numpy as np
import pickle as pk
from pynput.keyboard import Listener as KL
from pynput.mouse import Listener as ML
from pynput.keyboard import Controller as KC
pyautogui.PAUSE = 0


class Screen:
    def __init__(self):
        self.cap = mss.mss()
        left, top, width, height = pyautogui.getActiveWindow().box
        left, top, right, bottom = left+9, top, left+width-9, top+height-9
        self.region = (left, top, right, bottom)

    def shot(self):
        img = self.cap.grab(self.region)
        img = np.resize(np.array(img.raw), (img.height, img.width, 4))  # np.array(img)会报告警
        self.img = cv2.cvtColor(img, cv2.COLOR_BGRA2BGR)
        return self.img

    @staticmethod
    def show(img):
        cv2.namedWindow("a")  # 创建一个图片大小（cv2.WINDOW_NORMAL）的窗口
        cv2.imshow("a", img)  # 在该窗口显示图片
        cv2.waitKey(0)  # 等待Key关闭窗口，否则立即关闭
        cv2.destroyAllWindows()

    @staticmethod
    def get_location(state, pattern):
        match = cv2.matchTemplate(state, pattern, method=cv2.TM_CCOEFF_NORMED)
        _, value, _, location = cv2.minMaxLoc(match)
        print(f"{value:.2f}", location)
        return location[0] if value > 0.9 else 0


def start():
    run, kl = [0, 1], KL(on_press=lambda key: run.reverse() if key.__dict__.get("char") == "`" else 0)
    kl.start()
    while run[-1]: time.sleep(0.2)
    kl.stop()


def record(init_x=0, init_y=0):
    def timer(start=time.time()): return time.time() - start
    def press(key):
        if key.__dict__.get("char") == "`": run.reverse()
        else: msg.append((timer(), "press", key))
    def release(key):
        if key.__dict__.get("char") != "`": msg.append((timer(), "release", key))
    def click(x, y, b, p):
        if p: msg.append((timer(), f"{b}", (x-init_x, y-init_y)))

    run, msg, kl, ml = [0, 1], [], KL(on_press=press, on_release=release), ML(on_click=click)
    (kl.start(), ml.start())
    while run[-1]: time.sleep(0.2)
    (kl.stop(), ml.stop())
    [print(m) for m in msg]
    pk.dump(msg, open("route.pk", "wb"))


def execute(init_x=0, init_y=0):
    msg, kc, timer = pk.load(open("route.pk", "rb")), KC(), 0
    for m in msg:
        print(m)
        time.sleep(m[0] - timer)
        if m[1] == "press": kc.press(m[2])
        elif m[1] == "release": kc.release(m[2])
        elif m[1] == "Button.left": pyautogui.click(m[2][0]+init_x, m[2][1]+init_y)
        elif m[1] == "Button.right": pyautogui.rightClick(m[2][0]+init_x, m[2][1]+init_y)
        timer = m[0]


if __name__ =="__main__":
    start()
    env = Screen()
    # print("start record")
    # record(env.region[0], env.region[1])
    # print("end record")
    # start()
    print("start execute")
    execute(env.region[0], env.region[1])
    print("end execute")


